package cdu.sl.service.impl;

import cdu.sl.annotation.KeyAction;
import cdu.sl.common.PageResult;
import cdu.sl.entity.Department;
import cdu.sl.mapper.DepartmentDao;
import cdu.sl.mapper.EmployeeDao;
import cdu.sl.dto.EmpQueryParamDTO;
import cdu.sl.entity.Employee;
import cdu.sl.enumeration.KeyActionType;
import cdu.sl.mapper.specifications.EmployeeSpecifications;
import cdu.sl.service.EmployeeService;
import ch.qos.logback.classic.Logger;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
@Slf4j
public class EmployeeServiceImpl implements EmployeeService {

    private final EmployeeDao employeeDao;

    private final DepartmentDao departmentDao;

    /**
     * 修改职员信息
     *
     * @param emp 职员信息
     */
    @Override
    @KeyAction(KeyActionType.EMP_UPDATE)
    public void update(Employee emp) {
        Optional<Department> dep = departmentDao.findById(emp.getDepId());
        dep.ifPresent(department -> emp.setDepName(dep.get().getName()));
        employeeDao.save(emp);
    }

    /**
     * 删除职员
     *
     * @param id 职员id
     */
    @Override
    @KeyAction(KeyActionType.EMP_DELETE)
    public void delete(Integer id) {
        employeeDao.deleteById(id);
    }

    /**
     * 新增职员
     *
     * @param emp 职员信息
     */
    @Override
    @KeyAction(KeyActionType.EMP_INSERT)
    public void add(Employee emp) {
        Optional<Department> dep = departmentDao.findById(emp.getDepId());
        // 为职员所在部门信息赋值(冗余字段)
        dep.ifPresent(department -> emp.setDepName(dep.get().getName()));
        employeeDao.save(emp);
    }

    /**
     * 根据id查找职员
     *
     * @param id 职员id
     * @return 职员信息
     */
    @Override
    public Employee findById(Integer id) {
        Optional<Employee> opt = employeeDao.findById(id);
        opt.ifPresent(employee -> log.info("查询到员工信息：{}", employee));
        return opt.orElse(null);
    }

    /**
     * 获取所有职员信息
     *
     * @return 所有职员信息数据
     */
    @Override
    public List<Employee> findAll() {
        return employeeDao.findAll();
    }

    /**
     * 分页条件查询员工数据
     *
     * @param empQueryParam 分页参数与查询条件
     * @return 分页结果
     */
    @Override
    public PageResult<Employee> page(EmpQueryParamDTO empQueryParam) {
        // 设置分页参数
        Pageable pageable = PageRequest.of(empQueryParam.getPage() - 1, empQueryParam.getPageSize());

        // 定义分页查询结果
        Page<Employee> page;
        // 根据查询条件查询结果
        // 使用JPQL (本实验使用Specification)
        // page = employeeDao.findByOptionalParams(empQueryParam.getEmpName(), empQueryParam.getDepName(), pageable);
        Specification<Employee> spec = EmployeeSpecifications.withOptionalParams(empQueryParam.getEmpName(), empQueryParam.getDepName());
        page = employeeDao.findAll(spec, pageable);

        return new PageResult<>(page.getTotalElements(), page.getContent(),
                page.getNumber() + 1, page.getSize(), page.getTotalPages());
    }


}
